package cn.doyens.reggie.filter;

import cn.doyens.reggie.common.BaseContext;
import cn.doyens.reggie.common.R;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/*
*   <filter>
       <filter-name>loginCheckFilter</filter-name>
       <filter-class>cn.doyens.reggie.filter.LoginCheckFilter</filter-class>
   </filter>
   *
   * <filter-mapping>
          <filter-name>loginCheckFilter</filter-name>
          <url-pattern>/*</url-pattern>
      </filter-mapper>
*
* */
@Slf4j
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
public class LoginCheckFilter implements Filter {

    //创建路径校验工具类
    private static  final AntPathMatcher ANT_PATH_MATCHER = new AntPathMatcher();

    /**
     *  定义登陆过滤逻辑
     *    分析:
     *        1.获取请求的路径  通过HttpServletRequest对象调用getRequestURI方法获取请求路径  /common/login
     *        2.定义请求放行白名单       /employee/page
     *            String[] urlPaths = {"/employee/login","/employee/logout","/backend/**","/front/**"}
     *        3.使用获得的请求路径  对比urlPaths中的元素是否包含 根据判断结果 可以进行放行
     *        4.判断当前用户是否已经登陆  从session域中取出键为employee 的值 是否为空 如果不为空则表示用户已经登陆 直接放行
     *        5. 最后 通过response对象响应返回 R对象 提示没有登陆
     * @param servletRequest
     * @param servletResponse
     * @param filterChain
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
          // 1.获取请求的路径  通过HttpServletRequest对象调用getRequestURI方法获取请求路径  /common/login
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
         //获取uri   /employee/page
        String uri = request.getRequestURI();
        log.info("当前请求的uri为:"+uri);
        //2.定义请求放行白名单
        String[] urlPaths = {
                "/employee/login",
                "/employee/logout",
                "/user/sendMsg",
                "/user/login",
                "/common/**",
                "/backend/**",
                "/front/**",
                "/doc.html",
                "/webjars/**",
                "/swagger-resources",
                "/v2/api-docs"
        };
        //3.使用获得的请求路径  对比urlPaths中的元素是否包含 根据判断结果 可以进行放行
        boolean flag = checkUrl(urlPaths,uri);
        //根据判断结果 可以进行放行
        if(flag){
            //对本次请求放行
            filterChain.doFilter(request,response);
            return;//结束方法
        }
        // 4.判断当前用户是否已经登陆
        Long empId = (Long) request.getSession().getAttribute("employee");
        //判断empId是否为空  如果不为空则表示用户已经登陆 则直接放行
        if(empId!=null){
            //将当前登陆者的员工id值存入到ThreadLocal中
            BaseContext.setCurrentId(empId);
            //对本次请求放行
            filterChain.doFilter(request,response);
            return;//结束方法
        }

        // 4.判断当前用户是否已经登陆
        Long userId = (Long) request.getSession().getAttribute("user");
        //判断userId是否为空  如果不为空则表示用户已经登陆 则直接放行
        if(userId!=null){
            //将当前登陆者的员工id值存入到ThreadLocal中
            BaseContext.setCurrentId(userId);
            //对本次请求放行
            filterChain.doFilter(request,response);
            return;//结束方法
        }

        //5. 最后 通过response对象响应返回 R对象 提示没有登陆
        response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
        //response.sendRedirect(request.getContextPath()+"/backend/page/login/login.html");
    }

    public boolean checkUrl(String[] urlPaths, String uri) {
        //遍历数组
        for (String urlPath : urlPaths) {
            //通过工具类对象调用方法 判断请求路径是否 在白名单中出现过
            if(ANT_PATH_MATCHER.match(urlPath,uri)){
                //如果出现过则返回 true  表示 当前访问资源属于白名单资源
                return true;
            }
        }
       /* for (String urlPath : urlPaths) {
            //uri /backend/index.html      urlPath
            if(uri.startsWith(urlPath)){
                return true;
            }
        }*/

        return false;
    }
}
